package com.tnsw.facebookautoliker;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;

import com.tnsw.coreutils.AsyncManager;
import com.tnsw.coreutils.MyLog;
import com.tnsw.coreutils.database.DBActionListener;
import com.tnsw.coreutils.database.RecordBase;
import com.tnsw.coreutils.text.TextUtils;
import com.tnsw.coreutils.ui.BitmapCache;
import com.tnsw.facebookautoliker.base.FragmentBase;
import com.tnsw.facebookautoliker.database.DBManager;
import com.tnsw.facebookautoliker.database.FriendsList;
import com.tnsw.facebookautoliker.database.FriendsPost;
import com.tnsw.facebookautoliker.database.ObjectCache;
import com.tnsw.facebookautoliker.database.VFriendsPost;
import com.tnsw.facebookautoliker.helper.FacebookActionListener;
import com.tnsw.facebookautoliker.helper.FacebookBGManager;
import com.tnsw.facebookautoliker.helper.FacebookCommandObject;
import com.tnsw.facebookautoliker.helper.GeneralManager;
import com.tnsw.facebookautoliker.helper.command.DoLikeObject;
import com.tnsw.facebookautoliker.helper.command.DoUnlikePost;
import com.tnsw.facebookautoliker.helper.command.FQLBase;
import com.tnsw.facebookautoliker.helper.command.FQLInterface;
import com.tnsw.facebookautoliker.helper.command.GetHTTPPhoto;
import com.tnsw.facebookautoliker.helper.command.GetPhoto;
import com.tnsw.facebookautoliker.helper.command.GetPhotoFQL;
import com.tnsw.facebookautoliker.helper.command.LikeManager;
import com.tnsw.facebookautoliker.services.AutoLikerService;

public class LikeHistoryFragment extends FragmentBase implements Runnable, DBActionListener, OnItemClickListener, ListViewDragActionListener, FacebookActionListener, FQLInterface {
	
	private LayoutInflater inflater = null;
	private Context context;
	private ViewGroup root;
	
	private LinearLayout layoutUpdateHost;
	private ListView lvLikeHistory;
	private LikeHistoryAdapter adapter;
	
	private ListViewDragExtender lvExtender;
	
	private StandardUpdateView updateView;
	
	private View emptyView;
	
	private FacebookBGManager fbm;
	private DBManager dbm;
	private GeneralManager gm;
	private AutoLikerService aService;
	
	private FriendsPost currentFp;
	
	private String filterName = "";
	private FragmentAlertDialog dlg;
	
	public LikeHistoryFragment() {
		super();
		this.tag = "LikeHistoryFragment";
		//this.setHasOptionsMenu(true);
		
		this.aService = AutoLikerService.getInstance();
		this.setVisibleMenu(new Integer[] {R.id.menu_mainscreen_logout, R.id.menu_mainscreen_friendonly, R.id.menu_search});
		
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		
		this.context = (Context) this.getActivity();
		
		this.fbm = FacebookBGManager.getInstance(context);
		this.dbm = DBManager.getInstance(context);
		this.gm = GeneralManager.getInstance();
		
		this.dbm.registerActionListener(this);
		this.fbm.registerActionListener(this);
		
		this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		
		this.emptyView = (ViewGroup) this.inflater.inflate(R.layout.empty_pulldown, null);
		
		this.root = (ViewGroup) this.inflater.inflate(R.layout.likehistory, null);
		
		this.lvLikeHistory = (ListView) this.root.findViewById(R.id.lvLikeHistory);
		this.lvLikeHistory.setOnItemClickListener(this);
		this.layoutUpdateHost = (LinearLayout) this.root.findViewById(R.id.layoutUpdateHost);
				
		this.updateView = new StandardUpdateView(this.context, this.layoutUpdateHost);
		this.updateView.setListViewDragActionListener(this);
		this.layoutUpdateHost.addView(this.updateView.getView());
	
		this.adapter = new LikeHistoryAdapter(context, this.emptyView, this.updateView);
		this.adapter.setBitmapCache(this.bmpCache);
		this.lvLikeHistory.setAdapter(this.adapter);
		
		this.lvExtender = new ListViewDragExtender(context, this.lvLikeHistory, this.layoutUpdateHost, this.adapter);

		this.lvExtender.setListViewDragInterface(this.updateView);
		this.lvExtender.setUpdateView(this.updateView);
		this.lvExtender.setEnable(false);
		
		MyLog.d(tag, "Finishing onCreateView()");
		return(root);
	}
	
	@Override
	public void setBitmapCache(BitmapCache bmpCache) {
		super.setBitmapCache(bmpCache);
		if (this.adapter != null) {
			this.adapter.setBitmapCache(bmpCache);
		} else {
			MyLog.e(tag, "Cannot set bCache because adapter is null");
		}
	}
	
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		/*
		MyLog.d(tag, "> Logout=" + R.id.menu_mainscreen_logout);
		
		int i;
		int size = menu.size();
		for (i = 0; i < size; i++) {
			MenuItem item = menu.getItem(i);
			
			MyLog.d(tag, ">" + item.getTitle().toString() + ", " + item.getItemId());
			if (item.getItemId() != R.id.menu_mainscreen_logout) {
				item.setVisible(false);
			}
			
		}
		*/
	}

	@Override
	public void onTabReselected() {
		super.onTabReselected();
		
		View c = this.lvLikeHistory.getChildAt(0);
		int scrollY = -c.getTop() + this.lvLikeHistory.getFirstVisiblePosition() * c.getHeight();
		MyLog.d(tag, "scrollY=" + scrollY);
		
		if (scrollY != 0) {
			this.lvLikeHistory.smoothScrollToPosition(0);
		}

	}
	
	@Override
	public void onTabSelected() {
		super.onTabSelected();
		
		/*
		if (this.adapter != null) {
			if (this.adapter.getCount() < 2) {
				this.adapter.refreshFromDB();
				this.adapter.notifyDataSetChanged();	
			}
				
		}
		*/
		
	}
	
	@Override
	public void onFacebookCommandExecute(FacebookCommandObject fbco) {
		if (fbco instanceof FQLBase) {
			FQLBase fqlb = (FQLBase) fbco;
			if (fqlb.hasTag("caller")) {
				String caller = (String) fqlb.getTag("caller");
				if (caller.equals(this.getClass().getName())) {
					FriendsPost fp = (FriendsPost) fqlb.getTag("fp");
					if (fp.getStatus() == 0) {
						fp.setStatus(1);
					} else {
						fp.setStatus(0);
					}
				}
				
				if (this.context != null) {
					Activity a = (Activity) this.context;
					
					a.runOnUiThread(this);				
				}
				
			}
		}
	}
	
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
		FriendsPost fp = (FriendsPost) this.adapter.getItem(position);
		//MyLog.d(tag, "JSON=" + fp.raw_json);
		
		try {
			//JSONObject jo = new JSONObject(fp.raw_json);
			String actor_id = fp.actor_id;
			if (this.aService.getHashFriendsList().containsKey(actor_id) == false) {
				MyLog.e(tag, "Cannot find actor_id=" + actor_id + " from friends_list");
				return;
			}
			
			String name = this.aService.getHashFriendsList().get(actor_id).name;
			//String typeStt = LikeManager.getType(jo, name);
			String xid = fp.post_id.split("_")[1];
			String description = fp.description;
			
			//MyLog.d(tag, "type=" + typeStt + ", xid=" + xid);
			//this.aService.handleAttachment(jo, typeStt);
			
			GetPhotoFQL gp = new GetPhotoFQL(this.context, xid, description, fp.post_id);
			//gp.execute();
			MyLog.d(tag, "concurrent=" + this.fbm.getConcurrent());
			//this.gm.addNewQueue(gp, 2);
			
			//LikeManager lm = new LikeManager(context, this.aService.getSelfInfo());
			//lm.doLike(fp.post_id, fp, jo, name);
			
			if (fp.getStatus() == 0) {
				//MyLog.d(tag, "setStatus = 1");
				//fp.setStatus(1);
				String fql = "SELECT updated_time, likes, attachment, created_time, description, message, type, app_id, attachment, message, post_id, actor_id, like_info FROM stream WHERE post_id='" + fp.post_id + "'";   
				FQLBase fqlb = new FQLBase(this.context, fql, null);
				fqlb.setFQLInterface(this);
				fqlb.setPagingColumn(null);
				fqlb.setTag("position", position);
				fp.setRequestId(fqlb.requestId());
				fqlb.setTag("fp", fp);
				fqlb.setTag("caller", this.getClass().getName());
				
				fqlb.setParentFragmentBase(this);
				fqlb.execute();
				
			} else {
				this.fbm.cancel(fp.getRequestId());
				
				//MyLog.d(tag, "setStatus = 1");
				//fp.setStatus(0);
			}
			
			this.adapter.notifyDataSetChanged();
			
		} catch (Exception e) {
			MyLog.e(tag, "onItemClick - " + e.toString(), e);
		}

	}

	@Override
	public void onUpdating(StandardUpdateView stdUpdateView) {
		MyLog.d(tag, "Should update now");
		this.adapter.notifyDataSetChanged();
		this.aService.getTimerTask().execute("me()", "manual");

	}

	@Override
	public void onCancelled(StandardUpdateView stdUpdateView) {
		
	}

	@Override
	public void onRequestCompleted(Object sender, FacebookCommandObject fbco, int statusCode, Exception tr) {
		MyLog.d(tag, "onRequestCompleted(fbco=" + fbco.toString() + ", statusCode=" + statusCode + ")");

		this.updateView.hideLayout();
				
		if ( (fbco instanceof GetHTTPPhoto) && (fbco.getTag("owner") != null) && (fbco.getTag("owner").equals(this)) ) {
			GetHTTPPhoto gp = (GetHTTPPhoto) fbco;
			ObjectCache oc = (ObjectCache) gp.getTag("record");
			if (oc != null) {
				oc.local_path = gp.getPhotoPath();
				MyLog.d(tag, "updating record to: " + oc.toString());
				this.dbm.updateRecordByPrimarykey("object_cache", oc, true);
			}
			
		} else if (fbco instanceof DoUnlikePost) {
			Object caller = fbco.getTag("caller");
			if (caller != null) {
				if (caller.equals(this.adapter)) {
					if (statusCode == 1001) {
						MyLog.d(tag, "I should do something, isUIThread()=" + AsyncManager.isUiThread());
						
						if (this.dlg == null) {
							this.dlg = new FragmentAlertDialog();
							this.dlg.setContext(this.context);
							this.dlg.setParentFragmenrt(this);
							
							this.dlg.setMessage("Not supported yet");
							this.dlg.show(this.getActivity().getSupportFragmentManager(), "NSY");
							
						} else {
							this.dlg.show(this.getActivity().getSupportFragmentManager(), "NSY");
						}
					}
				}
			}
			
		} else if (fbco instanceof FQLBase) {
			FQLBase fqlb = (FQLBase) fbco;
			MyLog.d(tag, "fql=" + fqlb.getFQL());
			String caller = (String) fbco.getTag("caller");
			
			if (caller != null) {
				if (caller.equals(this.getClass().getName())) {
					FriendsPost fp = (FriendsPost) fbco.getTag("fp");
					fp.setStatus(0);
					if (statusCode == 1405) {
						// cancel
						MyLog.d(tag, "fqlb is cancalled");
						
					}
				}	
			}
			
		}
	}
	
	public void forceReload() {
		if (this.adapter != null) {
			this.adapter.refreshFromDB();
			
			if (this.context != null) {
				Activity a = (Activity) this.context;
				a.runOnUiThread(this);				
			}	
		}
	}

	@Override
	public void onRecordAffected(String action, String tableName, int primaryKey, RecordBase record) {
		//MyLog.d(tag, "onRecordAffect(action=" + action + ")");
		
		if (record instanceof FriendsList) {
			//MyLog.d(tag, "Yes, it's FriendsList");
			if ( (action.equals("insert")) || (action.equals("update")) ) {
				MyLog.d(tag, "Yes, it's insert or update");
				
				this.currentFp = null;
				
				if (this.context != null) {
					Activity a = (Activity) this.context;
					a.runOnUiThread(this);				
				}	
			}
			
		} else if (record instanceof FriendsPost) {
			if ( (action.equals("insert")) || (action.equals("update")) ) {
				
				MyLog.d(tag, "Status - friends_post is updated");
				this.currentFp = (FriendsPost) record;
				MyLog.d(tag, "getStatus=" + this.currentFp.getStatus());
				
 				if (this.context != null) {
					Activity a = (Activity) this.context;
					a.runOnUiThread(this);				
				}
			}
			
		} else if (record instanceof ObjectCache) {
			if (action.equals("insert") || action.equals("update") ) {
				if (this.context != null) {
					Activity a = (Activity) this.context;
					a.runOnUiThread(this);				
				}
			}
						
		} 
		
	}

	@Override
	public void run() {
		MyLog.d(tag, "run() to refresh ListView");
		try {

			if (this.currentFp != null) {
				this.adapter.updateRecord(this.currentFp);	
			}
						
			this.adapter.notifyDataSetChanged();
			MyLog.d(tag, "run() - OK");
			
		} catch (Exception e) {
			MyLog.e(tag, "run() - " + e.toString(), e);
		}
	}
	
	public void setFilterByName(String name) {
		if (this.adapter == null) {
			MyLog.w(tag, "Cannot setFilterByName(name=" + name + ") - adapter==null!");
			return;
		}
		
		this.filterName = name;
		if (this.filterName.length() >= 3) {
			this.adapter.setFilterByName(name);
		} else {
			this.adapter.setFilterByName("");
		}
		
		this.adapter.notifyDataSetChanged();
	}
	
	public void setDisplayOnlyFriend(boolean b) {
		this.adapter.setDisplayOnlyFriend(b);
		
		this.adapter.notifyDataSetChanged();
	}

	@Override
	public boolean onSingleRecordFetched(Object sender, int recordNo, JSONObject jo) {
		MyLog.d(tag, "Got refreshed friends_post");
		FQLBase fqlb = (FQLBase) sender;
		int position = (Integer) fqlb.getTag("position");
		FriendsPost fp = (FriendsPost) fqlb.getTag("fp");
		
		//fp.raw_json = jo.toString();
		//this.adapter.updateRecord(fp);
		this.dbm.updateRecordByPrimarykey("friends_post", fp, true);
		MyLog.d(tag, "updated raw json");
		
		return false;
	}

	@Override
	public void onEndQuery(Object sender, ArrayList<JSONObject> arrJ) {
		FQLBase fqlb = (FQLBase) sender;
		FriendsPost fp = (FriendsPost) fqlb.getTag("fp");
		fp.setStatus(0);
		this.adapter.notifyDataSetChanged();
	}
	
	@Override
	public void onResume() {
		super.onResume();
		
		if (this.getLastCommand() != null) {
			this.executeLastCommand();	
		}
	}

}
